package com.yfp.operation.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yfp.common.core.constant.MqttConstants;
import com.yfp.common.core.domain.R;
import com.yfp.common.core.exception.ServiceException;
import com.yfp.common.core.utils.GeoUtils;
import com.yfp.common.core.utils.StringUtils;
import com.yfp.common.log.service.AsyncLogService;
import com.yfp.common.redis.service.RedisService;
import com.yfp.common.security.utils.SecurityUtils;
import com.yfp.goods.api.RemoteGoodsService;
import com.yfp.goods.domain.ComboDetailImg;
import com.yfp.goods.domain.Goods;
import com.yfp.goods.domain.GoodsNutritive;
import com.yfp.minapp.auth.api.RemoteClientService;
import com.yfp.operation.domain.*;
import com.yfp.operation.domain.dto.*;
import com.yfp.operation.domain.vo.*;
import com.yfp.operation.enums.PackageStatusEnums;
import com.yfp.operation.enums.PickupGoodsTypeEnums;
import com.yfp.operation.mapper.*;
import com.yfp.operation.service.*;
import com.yfp.system.api.RemoteLogService;
import com.yfp.system.api.domain.SysOperationLog;
import com.yfp.operation.domain.*;
import com.yfp.operation.domain.dto.*;
import com.yfp.operation.domain.vo.*;
import com.yfp.operation.mapper.*;
import com.yfp.operation.service.*;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.sql.Timestamp;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.yfp.common.core.constant.CacheConstants.MINAPP_ORDER_TAKE_QR_CODE_KEY;

@Service
@Slf4j
public class DeviceServiceImpl implements DeviceService {

    @Resource
    private MachineService machineService;
    @Resource
    private DeviceCurrentComboPlanRoadService deviceCurrentComboPlanRoadService;
    @Resource
    private DeviceCurrentComboStockService deviceCurrentComboStockService;
    @Resource
    private MealReplacementService mealReplacementService;
    @Resource
    private OrderDetailService orderDetailService;
    @Resource
    private OrderComboService orderComboService;
    @Resource
    private WorkOrderService workOrderService;
    @Resource
    private OrderListService orderListService;
    @Resource
    private ComboService comboService;
    @Resource
    private MachineDamageService machineDamageService;
    @Resource
    private ComboPlanDeviceService comboPlanDeviceService;
    @Resource
    private ComboPlanService comboPlanService;
    @Resource
    private CPComboRoadService cpComboRoadService;
    @Resource
    private PlatformTransactionManager platformTransactionManager;
    @Resource
    private TransactionDefinition transactionDefinition;
    @Resource
    private DeviceCurrentComboPlanService deviceCurrentComboPlanService;
    @Resource
    private DeviceComboPlanNumService deviceComboPlanNumService;
    @Resource
    private PositionService positionService;
    @Resource
    private ClientService clientService;
    @Resource
    private MqttGateway mqttGateway;
    @Resource
    private TagComboService tagComboService;
    @Resource
    private ComboGoodsService comboGoodsService;
    @Resource
    private GoodsService goodsService;
    @Resource
    private ImgResourceService imgResourceService;
    @Resource
    private RedisService redisService;
    @Resource
    private RemoteClientService remoteClientService;
    @Resource
    private RemoteLogService remoteLogService;
    @Resource
    private AsyncLogService asyncLogService;
    // @Resource
    // private SysDictDataService sysDictDataService;
    @Resource
    private ComboMapper comboMapper;
    @Resource
    private TagComboMapper tagComboMapper;
    @Resource
    private GoodsMapper goodsMapper;
    @Resource
    private ComboGoodsMapper comboGoodsMapper;
    @Resource
    private ImgResourceMapper imgResourceMapper;
    @Resource
    private RemoteGoodsService remoteGoodsService;
    @Resource
    private ClientCouponMapper clientCouponMapper;
    @Resource
    private LotteryRecordsClientRecordsMapper lotteryRecordsClientRecordsMapper;
    @Resource
    private MallProductService mallProductService;

    /**
     * 获取当前用户的设备列表
     *
     * @param coordinateDTO 经纬度实体类
     * @return 设备列表
     */
    @Override
    public List<MachineVO> selectDeviceOperationList(CoordinateDTO coordinateDTO) {
        Long userId = SecurityUtils.getUserId();
        // 获取设备信息
        List<MachineDO> machineDOS = machineService.getMachineOperationByUserId(userId);
        List<MachineVO> machineVOS = BeanUtil.copyToList(machineDOS, MachineVO.class);

        // 查询当前设备下的套餐数量列表
        List<String> machineIds = machineDOS.stream().map(MachineDO::getMachineId).collect(Collectors.toList());
        List<DeviceCurrentComboPlanRoadDO> comboNumByMachineIds = deviceCurrentComboPlanRoadService.getComboNumByMachineIds(machineIds);

        // 根据设备id分组，统计套餐数量
        Map<String, Integer> quantityByMachineId = deviceCurrentComboPlanRoadService.statisticalQuantity(comboNumByMachineIds);

        machineVOS.forEach(machineVO -> {
            // 没查到的默认为0
            Integer sum = MapUtil.getInt(quantityByMachineId, machineVO.getMachineId(), 0);
            machineVO.setInventory(sum);
            // 根据经纬度计算距离
            Double distance = GeoUtils.calculateDistance(machineVO.getLatitude(), machineVO.getLongitude(), coordinateDTO.getLatitude(), coordinateDTO.getLongitude());
            machineVO.setDistance(distance);
        });
        // 按照设备编号排序
        machineVOS.sort(Comparator.comparing(MachineVO::getDistance));
        return machineVOS;
    }

    /**
     * 获取设备详情
     *
     * @param machineId 设备id
     * @return 设备详情
     */
    @Override
    public MachineVO selectInfo(String machineId) {
        Long userId = SecurityUtils.getUserId();
        // Long userId = 10L;
        // 获取设备信息
        MachineDO machineDOS = machineService.getMachineOperationByUserIdAndMachineId(userId, machineId);
        if (Objects.isNull(machineDOS)) {
            throw new ServiceException("未关联此设备");
        }
        MachineVO machineVO = BeanUtil.toBean(machineDOS, MachineVO.class);

        // 获取客服状态
        Boolean onlineCustomer = mealReplacementService.isOnlineCustomer(machineId);
        if (onlineCustomer) {
            machineVO.setReplacementStatus(1);
        } else {
            machineVO.setReplacementStatus(0);
        }

        // 获取点位名称
        PositionDO positionDO = positionService.getById(machineDOS.getPositionId());
        machineVO.setPositionName(positionDO.getPositonName());

        return machineVO;
    }

    @Override
    public List<OrderQueueVO> orderQueue(String machineId, String phone) {
        List<OrderQueueDTO> orderQueueDTOS = orderListService.orderQueue(machineId, phone);
        List<OrderQueueVO> orderQueueVOS = BeanUtil.copyToList(orderQueueDTOS, OrderQueueVO.class);
        return orderQueueVOS;
    }

    /**
     * 获取设备订单详情
     *
     * @param orderId 订单id
     * @return 设备订单详情
     */
    @Override
    public List<OrderInfoVO> orderInfo(String orderId) {
        List<OrderInfoVO> orderInfoVOS = orderDetailService.getByOrderId(orderId);
        return orderInfoVOS;
    }

    /**
     * 运营端一键制作
     *
     * @param orderDetailDTOS 订单详情实体类
     * @return
     */
    @Override
    public Boolean orderOperationMake(List<OrderDetailDTO> orderDetailDTOS) {
        log.info("运营端一键制作：orderDetailDTOS:{}", orderDetailDTOS);
        Map<String, List<OrderDetailDTO>> orderDetailByOrderId = orderDetailDTOS.stream().collect(Collectors.groupingBy(OrderDetailDTO::getOrderId));
        orderDetailByOrderId.forEach((orderId, orderDetails) -> {
            log.info("运营端一键制作：orderId:{}", orderId);
            List<OrderListDO> orderListDOS = orderListService.getByOrderSn(orderId);

            OrderComboDO orderComboDO = orderComboService.getOrderComboByOrderId(orderId);

            Client client = clientService.getByUserId(orderComboDO.getUserId());
            String headImg = Optional.ofNullable(client.getHeadImg()).orElse("https://test-operation-yfp.qafanle.com/assets/logo-YitrP-wl.png");

            OrderListDO orderListDO = CollUtil.getFirst(orderListDOS);
            OrderListDO orderListDO1 = new OrderListDO();
            orderListDO1.setOrderType("0");
            orderListDO = Optional.ofNullable(orderListDO).orElse(orderListDO1);

            String pickupNum = "";// 订单类型（0小程序，1设备）
            if (StrUtil.equals("0", orderListDO.getOrderType())) {
                pickupNum = "D" + StrUtil.subSufByLength(orderListDO.getUserMobile(), 4);
            } else if (StrUtil.equals("1", orderListDO.getOrderType())) {
                pickupNum = "D" + orderListDO.getCheckCode();
            }

            List<String> orderDetailIds = orderDetails.stream().map(item -> item.getOrderDetailId()).collect(Collectors.toList());
            List<OrderDetailDO> orderDetailDOS = orderDetailService.listByOrderDetailIds(orderDetailIds);
            orderDetailDOS.stream().peek(item -> item.setCount(1L)).collect(Collectors.toList());
            List<OrderDetailDTO> orderDetailDTOList = BeanUtil.copyToList(orderDetailDOS, OrderDetailDTO.class);


            OrderMakeDTO orderMakeDTO = new OrderMakeDTO();
            orderMakeDTO.setOrderId(orderId);
            orderMakeDTO.setPayTime(orderListDO.getPayTime().getTime());
            orderMakeDTO.setPickupGoodsType(PickupGoodsTypeEnums.FO2.getType());
            orderMakeDTO.setUserHeadUrl(headImg);
            orderMakeDTO.setPickupNum(pickupNum);
            orderMakeDTO.setPackageList(orderDetailDTOList);
            orderMakeDTO.setOperateType("operation_make");

            MqttDTO<OrderMakeDTO> orderMakeDTOMqttDTO = new MqttDTO<>();
            orderMakeDTOMqttDTO.setCmd(MqttConstants.ORDER_RECOVER);
            orderMakeDTOMqttDTO.setPayload(orderMakeDTO);

            // 检查设备状态
            MachineDO machineDO = machineService.getById(orderComboDO.getMachineId());
            if (StrUtil.equals("0", machineDO.getOnlineStatus().toString())) {
                throw new ServiceException("设备不在线");
            }
            if (!StrUtil.equals("1", machineDO.getOperationStatus().toString())) {
                throw new ServiceException("设备未在运营状态");
            }
            Boolean onlineCustomer = mealReplacementService.isOnlineCustomer(orderComboDO.getMachineId());
            if (!onlineCustomer) {
                throw new ServiceException("客服不在线");
            }

            /**
             * 主题是设备id
             */
            String jsonStr = JSONUtil.toJsonStr(orderMakeDTOMqttDTO, JSONConfig.create().setIgnoreNullValue(false));
            log.info("一键制作发送订单制作指令：{}", jsonStr);
            mqttGateway.sendToMqtt(orderComboDO.getMachineId(), jsonStr);

            // 更改套餐状态
            Date queueTime = new Date();
            LambdaUpdateWrapper<OrderDetailDO> update = Wrappers.lambdaUpdate(OrderDetailDO.class);
            update.set(OrderDetailDO::getStatus, PackageStatusEnums.WaitingToBeMade.getStatus());
            update.set(OrderDetailDO::getQueueTime, queueTime);
            update.in(OrderDetailDO::getOrderDetailId, orderDetailIds);
            orderDetailService.update(update);

            // 存储制作队列
            for (OrderDetailDO orderDetailDO : orderDetailDOS) {
                orderDetailDO.setQueueTime(queueTime);
            }
            setRedisMachineOrderDetail(orderDetailDOS);
        });

        return true;
    }

    /**
     * 小程序一键制作
     *
     * @param orderId 订单id
     * @return
     */
    @Override
    public Boolean orderMinMake(String orderId) {
        log.info("小程序一键制作：orderId:{}", orderId);
        List<OrderListDO> orderListDOS = orderListService.getByOrderSn(orderId);
        OrderListDO orderListDO = CollUtil.getFirst(orderListDOS);

        OrderComboDO orderComboDO = orderComboService.getOrderComboByOrderId(orderId);
        Client client = clientService.getByUserId(orderComboDO.getUserId());
        String headImg = Optional.ofNullable(client.getHeadImg()).orElse("https://test-operation-yfp.qafanle.com/assets/logo-YitrP-wl.png");

        List<OrderDetailDO> orderDetailDOS = orderDetailService.listByOrderIds(ListUtil.of(orderId));
        List<OrderDetailDTO> orderDetailDTOList = BeanUtil.copyToList(orderDetailDOS, OrderDetailDTO.class);

        AtomicInteger pickupNumCount = new AtomicInteger(1);
        orderDetailDTOList.forEach(item -> {
            String num = StrUtil.padPre(pickupNumCount.toString(), 2, '0');
            pickupNumCount.getAndIncrement();
            item.setPickupNum("D" + StrUtil.subSufByLength(orderListDO.getUserMobile(), 4) + "-" + num);
        });

        OrderMakeDTO orderMakeDTO = new OrderMakeDTO();
        orderMakeDTO.setOrderId(orderId);
        orderMakeDTO.setPayTime(orderListDO.getPayTime().getTime());
        orderMakeDTO.setPickupGoodsType(PickupGoodsTypeEnums.FO2.getType());
        orderMakeDTO.setUserHeadUrl(headImg);
        orderMakeDTO.setPickupNum("D" + StrUtil.subSufByLength(orderListDO.getUserMobile(), 4));
        orderMakeDTO.setPackageList(orderDetailDTOList);
        orderMakeDTO.setOperateType("operation_make");

        MqttDTO<OrderMakeDTO> orderMakeDTOMqttDTO = new MqttDTO<>();
        orderMakeDTOMqttDTO.setCmd(MqttConstants.ORDER_MAKE);
        orderMakeDTOMqttDTO.setPayload(orderMakeDTO);

        // 检查设备状态
        MachineDO machineDO = machineService.getById(orderComboDO.getMachineId());
        if (StrUtil.equals("0", machineDO.getOnlineStatus().toString())) {
            throw new ServiceException("设备不在线");
        }
        if (StrUtil.equals("2", machineDO.getOperationStatus().toString())) {
            throw new ServiceException("设备未在运营状态");
        }
        if (StrUtil.equalsAny(machineDO.getOperationStatus().toString(), "3", "4")) {
            throw new ServiceException("设备在保养中，请稍后重试~");
        }
        Boolean onlineCustomer = mealReplacementService.isOnlineCustomer(orderComboDO.getMachineId());
        if (!onlineCustomer) {
            throw new ServiceException("客服不在线");
        }

        // 存储制作队列
        Date queueTime = new Date();
        for (OrderDetailDO orderDetailDO : orderDetailDOS) {
            orderDetailDO.setQueueTime(queueTime);
        }
        setRedisMachineOrderDetail(orderDetailDOS);

        /**
         * 主题是设备id
         */
        String jsonStr = JSONUtil.toJsonStr(orderMakeDTOMqttDTO, JSONConfig.create().setIgnoreNullValue(false));
        log.info("小程序发送订单制作指令：{}", jsonStr);
        mqttGateway.sendToMqtt(orderComboDO.getMachineId(), jsonStr);
        return true;
    }


    /**
     * 缓存存储排队订单详情
     *
     * @param orderDetailDOS
     */
    public synchronized void setRedisMachineOrderDetail(List<OrderDetailDO> orderDetailDOS) {
        // List<RedisOrderDetail> redisOrderDetails = redisService.getCacheList(CacheConstants.MACHINE_ORDER_DETAIL_STATUS_LIST);
        // if (null == redisOrderDetails) {
        //     redisOrderDetails = new ArrayList<>();
        // }
        // RedisOrderDetail addRedisOrderDetail = null;
        // for (OrderDetailDO orderDetailDO : orderDetailDOS) {
        //
        //     // 查找缓存中是否已存在
        //     boolean add = true;
        //     for (RedisOrderDetail redisOrderDetail : redisOrderDetails) {
        //         if (redisOrderDetail.getDetailId().equals(orderDetailDO.getOrderDetailId())){
        //             add =false;
        //             break;
        //         }
        //     }
        //
        //     if (add){
        //         addRedisOrderDetail = new RedisOrderDetail();
        //         addRedisOrderDetail.setDetailId(orderDetailDO.getOrderDetailId());
        //         addRedisOrderDetail.setQueueTime(orderDetailDO.getQueueTime());
        //         redisOrderDetails.add(addRedisOrderDetail);
        //     }
        // }
        // if (null != redisOrderDetails && redisOrderDetails.size() > 0){
        //     log.info("添加缓存生产订单：{}", orderDetailDOS);
        //     redisService.setCacheList(CacheConstants.MACHINE_ORDER_DETAIL_STATUS_LIST, redisOrderDetails);
        // }
    }

    /**
     * 补货管理-报损数据查询-查询当前的库存
     *
     * @param machineId 设备id
     * @return 报损数据
     */
    @Override
    public List<DeviceCurrentComboPlanRoadVO> currentRoadStockList(String machineId) {
        List<DeviceCurrentComboPlanRoadDO> deviceCurrentComboPlanRoadDOS = deviceCurrentComboPlanRoadService.getAllByMachineId(machineId);
        List<String> comboIds = deviceCurrentComboPlanRoadDOS.stream().map(item -> item.getComboId()).collect(Collectors.toList());
        // 获取套餐名称
        Map<String, ComboDO> comboMapById = comboService.queryByIds(comboIds).stream().collect(Collectors.toMap(ComboDO::getComboId, item -> item, (k1, k2) -> k1));
        List<DeviceCurrentComboPlanRoadVO> deviceCurrentComboPlanRoadVOS = BeanUtil.copyToList(deviceCurrentComboPlanRoadDOS, DeviceCurrentComboPlanRoadVO.class);

        for (DeviceCurrentComboPlanRoadVO deviceCurrentComboPlanRoadVO : deviceCurrentComboPlanRoadVOS) {
            // 设置套餐名称
            ComboDO orDefault = comboMapById.getOrDefault(deviceCurrentComboPlanRoadVO.getComboId(), new ComboDO());
            deviceCurrentComboPlanRoadVO.setComboName(orDefault.getName());

        }
        return deviceCurrentComboPlanRoadVOS;
    }

    /**
     * 补货管理-报损数据提交
     *
     * @param damageDTOS 报损数据实体类
     * @return 是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean damageHandle(List<DamageDTO> damageDTOS) {
        if (CollUtil.isEmpty(damageDTOS)) {
            throw new ServiceException("请勾选报损列表");
        }
        String machineId = CollUtil.getFirst(damageDTOS).getMachineId();
        String userName = SecurityUtils.getUsername();
        SysOperationLog sysOperationLog = new SysOperationLog();
        sysOperationLog.setAccount(userName);
        sysOperationLog.setMachineId(machineId);
        sysOperationLog.setType(2);
        sysOperationLog.setParameter(damageDTOS.toString());
        asyncLogService.addOperationLog(sysOperationLog);
        List<DeviceCurrentComboPlanRoadDO> deviceCurrentComboPlanRoadDOS = deviceCurrentComboStockService.damageHandle(damageDTOS);

        log.info("设备id:{},报损参数:{}", machineId, damageDTOS);

        // 查询该设备 今日 付过钱没退款的，但是没工单的套餐id
        List<String> comboIds = orderListService.getByMachineIdAndStatus(machineId);
        if (!comboIds.isEmpty()) {
            Map<String, Long> countMap = comboIds.stream()
                    .collect(Collectors.groupingBy(n -> n, Collectors.counting()));
            for (String comboId : countMap.keySet()) {
                Long num = countMap.get(comboId);
                List<DeviceCurrentComboPlanRoadDO> dtoList = deviceCurrentComboPlanRoadDOS.stream().filter(item -> item.getComboId().equals(comboId))
                        .sorted((s1, s2) -> Integer.compare(Integer.parseInt(s1.getRoadNumber()), Integer.parseInt(s2.getRoadNumber()))).toList();

                for (DeviceCurrentComboPlanRoadDO damageDTO : dtoList) {
                    if (num <= 0) {
                        break;
                    }
                    // 获取该货道的数量
                    Integer comboNum = Integer.parseInt(damageDTO.getComboNum());

                    // 判断如果待减数量大于货道数量    则直接减掉
                    if (num >= comboNum) {
                        num -= comboNum;
                        // 赋值为0
                        damageDTO.setComboNum("0");
                    } else {
                        Long l = comboNum - num;
                        damageDTO.setComboNum(String.valueOf(l));
                        num = 0L;
                    }
                }

                Map<String, String> numMap = dtoList.stream().collect(Collectors.toMap(DeviceCurrentComboPlanRoadDO::getId, DeviceCurrentComboPlanRoadDO::getComboNum));
                for (DeviceCurrentComboPlanRoadDO damageDTO : deviceCurrentComboPlanRoadDOS) {
                    if (numMap.containsKey(damageDTO.getId())) {
                        String comboNum = numMap.get(damageDTO.getId());
                        damageDTO.setComboNum(comboNum);
                    }
                }
            }
        }


        deviceCurrentComboPlanRoadService.damageHandle(damageDTOS);
        machineDamageService.damageHandle(deviceCurrentComboPlanRoadDOS);
        MqttDTO<List<DamageDTO>> orderMakeDTOMqttDTO = new MqttDTO<>();
        orderMakeDTOMqttDTO.setCmd(MqttConstants.BREAKAGE);
        orderMakeDTOMqttDTO.setPayload(damageDTOS);
        log.info("消息:{}", JSONUtil.toJsonStr(orderMakeDTOMqttDTO));
        /**
         * 主题是设备id
         */
        mqttGateway.sendToMqtt(machineId, JSONUtil.toJsonStr(orderMakeDTOMqttDTO));
        return Boolean.TRUE;
    }


    /**
     * 查看库存情况
     *
     * @param machineId 设备id
     * @return
     */
    @Override
    public List<DeviceCurrentComboPlanRoadDO> roadInfo(String machineId) {

        // 根据设备id获取库存信息
        List<DeviceCurrentComboPlanRoadDO> list = deviceCurrentComboPlanRoadService.roadInfo(machineId);
        log.info("查看库存情况:{}", list);
        List<String> comboIds = list.stream().map(s -> s.getComboId()).collect(Collectors.toList());
        if (comboIds.isEmpty()) {
            return new ArrayList<DeviceCurrentComboPlanRoadDO>();
        }
        List<ComboDO> comboDOs = comboService.findByComboIds(comboIds);

        Map<String, ComboDO> map = comboDOs.stream().collect(Collectors.toMap(ComboDO::getComboId, c -> c));
        for (DeviceCurrentComboPlanRoadDO readDO : list) {
            readDO.setComboName(map.get(readDO.getComboId()).getName());
        }

        log.info("获取库存信息成功，设备id:{}", machineId);
        return list;
    }

    /**
     * 修改库存
     *
     * @param dccprs
     */
    @Transactional
    @Override
    public void updateRoad(List<DeviceCurrentComboPlanRoadDO> dccprs) {

        // 获取设备id
        String machineId = CollUtil.getFirst(dccprs).getMachineId();
        String userName = SecurityUtils.getUsername();
        SysOperationLog sysOperationLog = new SysOperationLog();
        sysOperationLog.setAccount(userName);
        sysOperationLog.setMachineId(machineId);
        sysOperationLog.setType(3);
        sysOperationLog.setParameter(dccprs.toString());
        asyncLogService.addOperationLog(sysOperationLog);
        // 查看当前库存信息
        List<DeviceCurrentComboPlanRoadDO> roadDOList = deviceCurrentComboPlanRoadService.roadInfo(machineId);
        // 根据货道号分成map
        Map<String, DeviceCurrentComboPlanRoadDO> roadDOMap = roadDOList.stream().collect(Collectors.toMap(DeviceCurrentComboPlanRoadDO::getRoadNumber, Function.identity()));
        // 创建map，用于记录每个套餐的变化总数量
        HashMap<String, Integer> comboNumMap = new HashMap<>();
        // 遍历修改后的数据
        for (DeviceCurrentComboPlanRoadDO dccpr : dccprs) {
            // 修改变化数量   正数为增加了  负数为减少了
            Integer num = Integer.parseInt(dccpr.getComboNum());
            if (roadDOMap.containsKey(dccpr.getRoadNumber())) {
                // 用修改后的数量减掉修改前的数量  得到变化数量
                DeviceCurrentComboPlanRoadDO roadDO = roadDOMap.get(dccpr.getRoadNumber());
                num -= Integer.parseInt(roadDO.getComboNum());
            }
            if (comboNumMap.containsKey(dccpr.getComboId())) {
                // 统计套餐变化数量
                Integer integer = comboNumMap.get(dccpr.getComboId());
                comboNumMap.put(dccpr.getComboId(), num + integer);
            } else {
                comboNumMap.put(dccpr.getComboId(), num);
            }
        }

        if (dccprs != null) {
            Timestamp timestamp = new Timestamp(System.currentTimeMillis());
            ArrayList<DeviceCurrentComboPlanRoadDO> roadDOS = new ArrayList<>();
            for (DeviceCurrentComboPlanRoadDO dccpr : dccprs) {
                DeviceCurrentComboPlanRoadDO roadDO = new DeviceCurrentComboPlanRoadDO();
                roadDO.setComboNum(dccpr.getComboNum());
                roadDO.setComboId(dccpr.getComboId());
                roadDO.setRoadNumber(dccpr.getRoadNumber());
                roadDO.setMachineId(dccpr.getMachineId());
                roadDO.setUpdateTime(timestamp);
                roadDO.setComboName(dccpr.getComboName());
                roadDO.setCPlanId(dccpr.getCPlanId());
                roadDO.setCreateTime(dccpr.getCreateTime());
                roadDO.setDate(dccpr.getDate());
                roadDO.setId(dccpr.getId());
                roadDOS.add(roadDO);
            }

            ArrayList<DeviceCurrentComboPlanRoadDO> dccprList = new ArrayList<>();
            ArrayList<DeviceComboPlanNumDO> dcpnList = new ArrayList<>();
            ArrayList<DeviceCurrentComboStockDO> dccsList = new ArrayList<>();

            // 获取当前线上库存
            List<DeviceCurrentComboStockDO> stockDOS = deviceCurrentComboStockService.getByMacineId(machineId);
            Map<String, DeviceCurrentComboStockDO> stockDOMap = stockDOS.stream().collect(Collectors.toMap(DeviceCurrentComboStockDO::getComboId, Function.identity()));
            for (String comboId : stockDOMap.keySet()) {
                if (comboNumMap.containsKey(comboId)) {
                    Integer comboNum = comboNumMap.get(comboId);
                    DeviceCurrentComboStockDO deviceCurrentComboStockDO = stockDOMap.get(comboId);
                    Integer comboNum1 = deviceCurrentComboStockDO.getComboNum();
                    if ((comboNum1 + comboNum) < 0) {
                        throw new ServiceException("修改库存失败，修改后套餐数量不能小于已售但未取餐的数量");
                    }
                    deviceCurrentComboStockDO.setComboNum(comboNum1 + comboNum);
                    log.info("线上库存:{},套餐变化数量:{}", deviceCurrentComboStockDO.getComboNum(), comboNum);
                    dccsList.add(deviceCurrentComboStockDO);
                }
            }

            // 获取投放记录
//            List<String> comboIds = deviceComboPlanNumService.getCPlanComboIds(machineId);
            List<DeviceComboPlanNumDO> numDOS = deviceComboPlanNumService.getByMacineId(machineId);
            Map<String, DeviceComboPlanNumDO> numDOMap = numDOS.stream().collect(Collectors.toMap(DeviceComboPlanNumDO::getComboId, Function.identity()));
            for (String comboId : numDOMap.keySet()) {
                if (comboNumMap.containsKey(comboId)) {
                    Integer comboNum = comboNumMap.get(comboId);
                    DeviceComboPlanNumDO deviceComboPlanNumDO = numDOMap.get(comboId);
                    Integer comboNum1 = deviceComboPlanNumDO.getComboNum();
                    deviceComboPlanNumDO.setComboNum(comboNum1 + comboNum);
                    dcpnList.add(deviceComboPlanNumDO);
                }
            }


            dccprs.forEach(dccpr -> {
                dccpr.setUpdateTime(timestamp);
                dccprList.add(dccpr);
            });
            log.info("修改货道信息:{}", dccprList);
            deviceCurrentComboPlanRoadService.batchUpdate(dccprList);

            HashMap<String, DeviceCurrentComboPlanRoadDO> map = new HashMap<>();
            dccprs.forEach(dccpr -> {
                if (map.containsKey(dccpr.getComboId())) {
                    DeviceCurrentComboPlanRoadDO aDo = map.get(dccpr.getComboId());
                    Integer num = Integer.parseInt(aDo.getComboNum()) + Integer.parseInt(dccpr.getComboNum());
                    aDo.setComboNum(num.toString());
                    map.put(dccpr.getComboId(), aDo);
                } else {
                    map.put(dccpr.getComboId(), dccpr);
                }
            });

//            for (String key : map.keySet()) {
//                DeviceCurrentComboPlanRoadDO roadDO = map.get(key);
//                DeviceCurrentComboStockDO deviceCurrentComboStockDO = new DeviceCurrentComboStockDO();
//                deviceCurrentComboStockDO.setComboNum(Integer.parseInt(roadDO.getComboNum()));
//                deviceCurrentComboStockDO.setComboId(roadDO.getComboId());
//                deviceCurrentComboStockDO.setMachineId(roadDO.getMachineId());
//                deviceCurrentComboStockDO.setUpdateTime(new Timestamp(System.currentTimeMillis()));
//                deviceCurrentComboStockDO.setStockSnyTime(new Timestamp(System.currentTimeMillis()));
//                dccsList.add(deviceCurrentComboStockDO);
//
//                // 设备投放量记录
//                DeviceComboPlanNumDO countDO = new DeviceComboPlanNumDO();
//                countDO.setComboNum(Integer.parseInt(roadDO.getComboNum()));
//                countDO.setMachineId(roadDO.getMachineId());
//                countDO.setComboId(roadDO.getComboId());
//                countDO.setUpdateTime(timestamp);
//                dcpnList.add(countDO);
//            }


            deviceComboPlanNumService.batchUpdate(dcpnList);
            deviceCurrentComboStockService.batchUpdate(dccsList);
            List<ReplenishVo> replenishTabs = noticeMachine(roadDOS);
//            String machineId = CollUtil.getFirst(roadDOS).getMachineId();
            //
            // // 计算预估到手价格
            // // 列表中的套餐需要分别判断，分别取优惠力度最大优惠券的预估金额
            // List<ReplenishDTO> replenishDTOS = BeanUtil.copyToList(replenishTabs, ReplenishDTO.class);
            // // 根据套餐id去重
            // List<ReplenishDTO> values = replenishDTOS.stream().collect(Collectors.toMap(ReplenishDTO::getComboId, Function.identity(), (e1, e2) -> e1)).values().stream().toList();
            // Response<Map<String, ReplenishDTO.Marketing>> mapResponse = remoteClientService.computeEstimatedPrice(machineId, values);
            // if (mapResponse.getCode().equals(ResponseEnum.OPERATOR_SUCCESS.getCode())) {
            //     Map<String, ReplenishDTO.Marketing> data = mapResponse.getData();
            //     replenishTabs.stream().peek(item -> {
            //         ReplenishDTO.Marketing marketing = data.get(item.getComboId());
            //         ReplenishDTO.Marketing bean = BeanUtil.toBean(marketing, ReplenishDTO.Marketing.class);
            //
            //         MarketingTab marketing1 = item.getMarketing();
            //         marketing1.setDiscountedAfterPrice(bean.getDiscountedAfterPrice());
            //         marketing1.setClientCouponId(bean.getClientCouponId());
            //     }).collect(Collectors.toList());
            // } else {
            //     replenishTabs.stream().peek(item -> {
            //         MarketingTab marketing1 = item.getMarketing();
            //         marketing1.setDiscountedAfterPrice(new BigDecimal(marketing1.getApplietAmount()));
            //     }).collect(Collectors.toList());
            // }

            // 发送MQTT同步计划
            syncPlanMqtt(replenishTabs, machineId);

            log.info("修改库存成功");
        }
    }


    /**
     * 获取同步计划
     *
     * @param machineId
     * @return
     */
    @Transactional
    @Override
    public List<DeviceCurrentComboPlanRoadVO> submitPlan(String machineId) {
        long l = System.currentTimeMillis();
        // 获取当前的时间
        Timestamp currentTime = new Timestamp(l);
        List<DeviceCurrentComboPlanRoadVO> list = comboPlanDeviceService.getByMachineIdAndDate(machineId, currentTime);
        if (list.isEmpty()) {
            log.info("该设备没有投放计划");
            return new ArrayList<>();
        }
        return list;
    }


    /**
     * 提交
     *
     * @param comboList 数据包
     */
    @Transactional
    @Override
    public void deviceComboStockSync(List<DeviceCurrentComboPlanRoadDO> comboList) {

        log.info("提交计划入参:{}", comboList);

        // 判空
        if (comboList == null) {
            log.warn("设备套餐库存同步失败.原因：没有投放计划");
            return;
        }
        // 获取设备id
        String machineId = CollUtil.getFirst(comboList).getMachineId();
        String userName = SecurityUtils.getUsername();
        SysOperationLog sysOperationLog = new SysOperationLog();
        sysOperationLog.setAccount(userName);
        sysOperationLog.setMachineId(machineId);
        sysOperationLog.setType(1);
        sysOperationLog.setParameter(comboList.toString());
        asyncLogService.addOperationLog(sysOperationLog);
        // 入库
//        TransactionStatus transactionStatus = platformTransactionManager.getTransaction(transactionDefinition);
        try {

            // 获取套餐计划id
            String cPlanId = CollUtil.getFirst(comboList).getCPlanId();
            // 清空设备的投放计划信息
            deviceCurrentComboPlanService.deleteByMachineId(machineId);
            deviceCurrentComboPlanRoadService.deleteByMachineId(machineId);
            // 清空设备的库存信息
            deviceCurrentComboStockService.deleteByMachineId(machineId);
//            // 清掉当前设备今天提交的数据
//            deviceComboPlanNumService.deleteByMachineId(machineId);
            // 更新设备计划
            DeviceCurrentComboPlan dcp = new DeviceCurrentComboPlan();
            dcp.setCPlanId(cPlanId);
            dcp.setMachineId(machineId);
            dcp.setCPlanSnyTime(new Timestamp(System.currentTimeMillis()));
            dcp.setCreateTime(new Timestamp(System.currentTimeMillis()));
            dcp.setUpdateTime(new Timestamp(System.currentTimeMillis()));
            deviceCurrentComboPlanService.insert(dcp);

            HashMap<String, DeviceComboPlanNumDO> planNumDOHashMap = new HashMap<>();

            comboList.forEach(dccpr -> {
                dccpr.setMachineId(machineId);
                dccpr.setCreateTime(new Timestamp(System.currentTimeMillis()));
                dccpr.setUpdateTime(new Timestamp(System.currentTimeMillis()));
                String comboId = dccpr.getComboId();
                if (planNumDOHashMap.containsKey(comboId)) {
                    DeviceComboPlanNumDO planNumDO = planNumDOHashMap.get(comboId);
                    Integer num = planNumDO.getComboNum();
                    planNumDO.setComboNum(num + Integer.parseInt(dccpr.getComboNum()));
                    planNumDOHashMap.put(comboId, planNumDO);
                } else {
                    DeviceComboPlanNumDO deviceComboPlanNumDO = new DeviceComboPlanNumDO();
                    deviceComboPlanNumDO.setCPlanId(cPlanId);
                    deviceComboPlanNumDO.setMachineId(machineId);
                    deviceComboPlanNumDO.setComboId(comboId);
                    deviceComboPlanNumDO.setComboNum(Integer.parseInt(dccpr.getComboNum()));
                    deviceComboPlanNumDO.setCreateTime(new Timestamp(System.currentTimeMillis()));
                    deviceComboPlanNumDO.setUpdateTime(new Timestamp(System.currentTimeMillis()));
                    planNumDOHashMap.put(comboId, deviceComboPlanNumDO);
                }
            });


            // 查询该设备 今日 付过钱没退款的，但是没工单的套餐id
            List<String> comboIds = orderListService.getByMachineIdAndStatus(machineId);
            Map<String, Long> countMap = null;
            if (!comboIds.isEmpty()) {
                countMap = comboIds.stream()
                        .collect(Collectors.groupingBy(n -> n, Collectors.counting()));
            }


            ArrayList<DeviceComboPlanNumDO> deviceComboPlanNumDOS = new ArrayList<>();
            for (String comboId : planNumDOHashMap.keySet()) {
                DeviceComboPlanNumDO deviceComboPlanNumDO = planNumDOHashMap.get(comboId);
                if (null != countMap && countMap.containsKey(comboId)) {
                    // 减掉没取走的数量
                    Integer comboNum = countMap.get(comboId).intValue();
                    Integer comboNum1 = deviceComboPlanNumDO.getComboNum();
                    if (comboNum1 >= comboNum) {
                        deviceComboPlanNumDO.setComboNum(comboNum1 - comboNum);
                    } else {
                        deviceComboPlanNumDO.setComboNum(0);
                    }
                }
                deviceComboPlanNumDOS.add(deviceComboPlanNumDO);
            }

            // 设备投放量表入库
            deviceComboPlanNumService.insertAll(deviceComboPlanNumDOS);

            deviceCurrentComboPlanRoadService.insertAll(comboList);

            // 更新库存
            Map<String, DeviceCurrentComboStockDO> devStock = new HashMap<>();
            comboList.forEach(item -> {
                String comboId = item.getComboId();
                String comboNum = item.getComboNum();
                String machineId1 = item.getMachineId();
                Timestamp date = item.getDate();
                String cpId = item.getCPlanId();
                DeviceCurrentComboStockDO dcStock = devStock.get(comboId);
                if (dcStock == null) {
                    DeviceCurrentComboStockDO stock = new DeviceCurrentComboStockDO();
                    stock.setDate(date);
                    stock.setCPlanId(cpId);
                    stock.setComboId(comboId);
                    stock.setComboNum(Integer.parseInt(comboNum));
                    stock.setMachineId(machineId1);
                    stock.setStockSnyTime(new Timestamp(System.currentTimeMillis()));
                    stock.setUpdateTime(new Timestamp(System.currentTimeMillis()));
                    stock.setCreateTime(new Timestamp(System.currentTimeMillis()));
                    devStock.put(comboId, stock);
                } else {
                    dcStock.setComboNum(dcStock.getComboNum() + Integer.parseInt(comboNum));
                }
            });

            List<DeviceCurrentComboStockDO> dccsList = new ArrayList<>();


            // 入库
            for (String comboId : devStock.keySet()) {
                DeviceCurrentComboStockDO deviceCurrentComboStockDO = devStock.get(comboId);
                if (null != countMap && countMap.containsKey(comboId)) {
                    // 减掉没取走的数量
                    Integer comboNum = countMap.get(comboId).intValue();
                    Integer comboNum1 = deviceCurrentComboStockDO.getComboNum();
                    if (comboNum1 >= comboNum) {
                        deviceCurrentComboStockDO.setComboNum(comboNum1 - comboNum);
                    } else {
                        deviceCurrentComboStockDO.setComboNum(0);
                    }
                }
                dccsList.add(deviceCurrentComboStockDO);
            }
            deviceCurrentComboStockService.insertAll(dccsList);


            // 通知设备
            List<ReplenishVo> replenishTabs = noticeMachine(comboList);

            // // 计算预估到手价格
            // // 列表中的套餐需要分别判断，分别取优惠力度最大优惠券的预估金额
            // List<ReplenishDTO> replenishDTOS = BeanUtil.copyToList(replenishTabs, ReplenishDTO.class);
            // // 根据套餐id去重
            // List<ReplenishDTO> values = replenishDTOS.stream().collect(Collectors.toMap(ReplenishDTO::getComboId, Function.identity(), (e1, e2) -> e1)).values().stream().toList();
            // Response<Map<String, ReplenishDTO.Marketing>> mapResponse = remoteClientService.computeEstimatedPrice(machineId, values);
            // if (mapResponse.getCode().equals(ResponseEnum.OPERATOR_SUCCESS.getCode())) {
            //     Map<String, ReplenishDTO.Marketing> data = mapResponse.getData();
            //     replenishTabs.stream().peek(item -> {
            //         ReplenishDTO.Marketing marketing = data.get(item.getComboId());
            //         ReplenishDTO.Marketing bean = BeanUtil.toBean(marketing, ReplenishDTO.Marketing.class);
            //
            //         MarketingTab marketing1 = item.getMarketing();
            //         marketing1.setDiscountedAfterPrice(bean.getDiscountedAfterPrice());
            //         marketing1.setClientCouponId(bean.getClientCouponId());
            //     }).collect(Collectors.toList());
            // } else {
            //     replenishTabs.stream().peek(item -> {
            //         MarketingTab marketing1 = item.getMarketing();
            //         marketing1.setDiscountedAfterPrice(new BigDecimal(marketing1.getApplietAmount()));
            //     }).collect(Collectors.toList());
            // }

            // 发送MQTT同步计划
            syncPlanMqtt(replenishTabs, machineId);
            // 提交事务
//            platformTransactionManager.commit(transactionStatus);
            log.info("提交设备投放计划成功，设备id信息:{}", machineId);
        } catch (Exception e) {
            // 事物回滚
//            platformTransactionManager.rollback(transactionStatus);
//            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            log.warn("提交设备投放计划失败.设备id信息:{} 产生异常:", machineId, e);
        }
    }

    /**
     * 获取当前投资人用户的设备列表
     *
     * @param coordinateDTO 经纬度实体类
     * @return 设备列表
     */
    @Override
    public List<MachineVO> selectDeviceInvestorList(CoordinateDTO coordinateDTO) {
        Long userId = SecurityUtils.getUserId();
        // 获取设备信息
        List<MachineDO> machineDOS = machineService.getMachineInvestorByUserId(userId);
        List<MachineVO> machineVOS = BeanUtil.copyToList(machineDOS, MachineVO.class);

        machineVOS.forEach(machineVO -> {
            // 根据经纬度计算距离
            Double distance = GeoUtils.calculateDistance(machineVO.getLatitude(), machineVO.getLongitude(), coordinateDTO.getLatitude(), coordinateDTO.getLongitude());
            machineVO.setDistance(distance);
        });

        // 按照设备编号排序
        machineVOS.sort(Comparator.comparing(MachineVO::getDistance));
        return machineVOS;
    }

    @Override
    @Transactional
    public void setMachineOrderDetail(List<OrderDetailDO> orderDetailDO) {
        setRedisMachineOrderDetail(orderDetailDO);
    }

    /**
     * 核销实体券
     * @param ccId
     */
    @Override
    @Transactional
    public void verification(Long ccId) {
        // 核销实体券
        ClientCoupon clientCoupon = clientCouponMapper.selectById(ccId);
        if (clientCoupon.getStatus() != 1) {
            throw new ServiceException("核销失败,券已被核销或已失效！");
        }
        LambdaUpdateWrapper<ClientCoupon> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(ClientCoupon::getId, ccId);
        wrapper.set(ClientCoupon::getStatus, 2);
        wrapper.set(ClientCoupon::getVerifyUserId, SecurityUtils.getUserId());
        wrapper.set(ClientCoupon::getVerifyTime, new Date());
        clientCouponMapper.update(null, wrapper);
//        LambdaUpdateWrapper<LotteryRecordsClientRecords> wrapper1 = new LambdaUpdateWrapper<>();
//        ArrayList<Long> longs = new ArrayList<>();
//        longs.add(ccId);
//        wrapper1.eq(LotteryRecordsClientRecords::getClientCouponId, JSON.toJSON(longs).toString());
//        wrapper1.set(LotteryRecordsClientRecords::getReceiveState, 1);
//        lotteryRecordsClientRecordsMapper.update(null, wrapper1);

    }


    /**
     * 通知设备同步库存信息
     *
     * @param comboList
     * @return
     */
    public List<ReplenishVo> noticeMachine(List<DeviceCurrentComboPlanRoadDO> comboList) {
        // 获取设备优惠金额
        // SysDictData deviceDiscountAmount = sysDictDataService.getByType("device_discount_amount");
        // 获取套餐计划id
        String cPlanId = CollUtil.getFirst(comboList).getCPlanId();
        String machineId = CollUtil.getFirst(comboList).getMachineId();
        List<String> comboIds = comboList.stream().map(s -> s.getComboId()).collect(Collectors.toList());
        LambdaQueryWrapper<ComboDO> wrapper = new LambdaQueryWrapper<ComboDO>().in(ComboDO::getComboId, comboIds);
        List<ComboDO> combos = comboMapper.selectList(wrapper);
//        List<Combo> comboDOS = comboMapper.findByComboIds(comboIds);
        Map<String, ComboDO> comboDOMap = combos.stream().collect(Collectors.toMap(ComboDO::getComboId, Function.identity()));

        List<TagCombo> tagCombos = new ArrayList<>();
        List<String> tagIds = combos.stream().map(comboDO -> comboDO.getTagId()).filter(tagId -> StrUtil.isNotBlank(tagId)).distinct().collect(Collectors.toList());
        if (CollUtil.isNotEmpty(tagIds)) {
            for (String tagId : tagIds) {
                if (StringUtils.isNotEmpty(tagId)) {
                    List<String> strings = Arrays.asList(tagId.split(","));
                    List<TagCombo> list = tagComboMapper.findByTagIds(strings);
                    tagCombos.addAll(list);
                }
            }
        }

        List<GoodsDO> goodsDOList = goodsMapper.getAll();
        Map<String, GoodsDO> goodsDOMap = goodsDOList.stream().collect(Collectors.toMap(GoodsDO::getGoodsId, Function.identity()));

        List<ImgResourceDO> imgResourceDOList = imgResourceMapper.getAll();
        Map<String, ImgResourceDO> imgMap = imgResourceDOList.stream().collect(Collectors.toMap(ImgResourceDO::getImgId, Function.identity()));
        LambdaQueryWrapper<ComboGoodsDO> queryWrapper = new LambdaQueryWrapper<>();
        List<ComboGoodsDO> comboGoodsDOs = comboGoodsMapper.selectList(queryWrapper);
        // 封装数据返回设备
        List<ReplenishVo> replenishVos = new ArrayList<>();

        ReplenishVo replenishVo = null;
        for (DeviceCurrentComboPlanRoadDO dccpr : comboList) {
            replenishVo = new ReplenishVo();
            // 套餐id
            replenishVo.setComboId(dccpr.getComboId());
            // 套餐名称
            replenishVo.setComboName(dccpr.getComboName());
            // 套餐数量
            replenishVo.setComboNum(Integer.parseInt(dccpr.getComboNum()));
            // 货道号
            replenishVo.setRoadNumber(Integer.parseInt(dccpr.getRoadNumber()));

            // 创建营销对象
            ReplenishVo.Marketing marketing = replenishVo.new Marketing();

            List<ReplenishVo.ComboLabel> list = new ArrayList<>();
            // 如果套餐map包含该套餐id
            if (comboDOMap.containsKey(dccpr.getComboId())) {
                // 套餐信息
                ComboDO comboDO = comboDOMap.get(dccpr.getComboId());
                // 保质期
                replenishVo.setExpireDay(comboDO.getExpireDay());
                replenishVo.setHeatTime(comboDO.getHeatTime());
                // 小程序价格
                // String dictValue = deviceDiscountAmount.getDictValue();
                // BigDecimal miniPrice = NumberUtil.sub(comboDO.getSalePrice(), dictValue);
                // if (NumberUtil.isLess(miniPrice, BigDecimal.ZERO)) {
                //     miniPrice = BigDecimal.ZERO;
                // }
                marketing.setApplietAmount(Double.valueOf(comboDO.getMiniPrice()));
                // 设备价格
                marketing.setDeviceAmount(Double.valueOf(comboDO.getSalePrice()));
                // 会员价格
                marketing.setVipAmount(Double.valueOf(comboDO.getVipPrice()));
//                marketingTab.setMarketingId("");
//                marketingTab.setComboId(dccpr.getComboId());
                if (!tagCombos.isEmpty() && comboDO.getTagId() != null) {
                    List<String> tagIdList = Arrays.asList(comboDO.getTagId().split(","));
                    for (String tagId : tagIdList) {
                        if (StringUtils.isEmpty(tagId)){
                            continue;
                        }
                        List<TagCombo> tagComboList = tagCombos.stream().filter(tagCombo -> tagCombo.getTagId().equals(tagId)).collect(Collectors.toList());
                        TagCombo tagCombo = tagComboList.get(0);
                        ReplenishVo.ComboLabel comboLabel = replenishVo.new ComboLabel();
                        // 套餐标签id 列表 字符窜
                        comboLabel.setLabelName(tagCombo.getTagName());
                        comboLabel.setLevel(0);
                        comboLabel.setColor(tagCombo.getColor());
                        list.add(comboLabel);
                    }
                }
                ImgResourceDO imgResourceDO = imgMap.get(comboDO.getThumb());
                // 套餐图片路径
                replenishVo.setThumbUrl(imgResourceDO.getUrl());
                // 味道
                ReplenishVo.Tastes tastes = replenishVo.new Tastes();
                tastes.setSpicy(Convert.toInt(comboDO.getTaste()));
                replenishVo.setTastes(tastes);
            }
            replenishVo.setMarketing(marketing);
            replenishVo.setComboLabel(list);
            //  套餐配菜
            com.yfp.common.core.domain.R<List<Goods>> goods = remoteGoodsService.queryByComboId(dccpr.getComboId());

            // 套餐组成
            ArrayList<GoodsData> dataArrayList = new ArrayList<>();
            List<ReplenishVo.GoodsData> goodsDataList = new ArrayList<>();
            List<ComboGoodsDO> comboGoodsList = comboGoodsDOs.stream().filter(combogoodsDO -> combogoodsDO.getComboId().equals(dccpr.getComboId())).collect(Collectors.toList());
            ReplenishVo.GoodsData goodsData = null;
            for (ComboGoodsDO comboGoods : comboGoodsList) {
                GoodsDO goodsDO = goodsDOMap.get(comboGoods.getGoodsId());
                // 商品营养表
                R<List<GoodsNutritive>> rGoodsNutritive = remoteGoodsService.queryGoodsNutritiveByGoodsId(goodsDO.getGoodsId());
                List<GoodsNutritive> goodsNutritives = rGoodsNutritive.getData();
                if (!goodsNutritives.isEmpty()) {
                    for (GoodsNutritive goodsNutritive : goodsNutritives) {
                        goodsData = replenishVo.new GoodsData();
                        goodsData.setGoodsNutritive(goodsNutritive.getNutritive());
                        if (!StrUtil.isEmpty(goodsNutritive.getValue())) {
                            goodsData.setValue(Double.valueOf(goodsNutritive.getValue()));
                        }
                        goodsDataList.add(goodsData);
                    }
                }
            }

            // 查询套餐资源
            com.yfp.common.core.domain.R<List<ComboDetailImg>> comboDetailImg = remoteGoodsService.queryComboDetailImg(dccpr.getComboId());
            List<ComboDetailImg> comboDetailImgs = comboDetailImg.getData();
            List<ReplenishVo.Resource> resourceList = new ArrayList<>();
            ReplenishVo.Resource resource = null;
            if (!CollUtil.isEmpty(comboDetailImgs)) {
                for (ComboDetailImg detailImg : comboDetailImgs) {
                    resource = replenishVo.new Resource();
                    com.yfp.common.core.domain.R<String> rResourceUrl = remoteGoodsService.getResourceUrl(detailImg.getResourceType(), detailImg.getResourceId());
                    String resourceUrl = rResourceUrl.getData();
                    resource.setResourceType(detailImg.getResourceType() + "");
                    resource.setResourceUrl(resourceUrl);
                    resourceList.add(resource);
                }
            }
            ReplenishVo.ComboDetailData comboDetailData = replenishVo.new ComboDetailData();
            comboDetailData.setResourceList(resourceList);


            // 套餐组成
            replenishVo.setGoods(goods.getData());
            replenishVo.setGoodsData(goodsDataList);
            replenishVo.setComboDetailData(comboDetailData);
            // 添加集合
            replenishVos.add(replenishVo);
        }
        log.info("noticeMachine消息:{}", JSONUtil.toJsonStr(replenishVos));
        return replenishVos;
    }

    private void syncPlanMqtt(List<ReplenishVo> replenishTabList, String machineId) {
        MqttDTO<List<ReplenishVo>> orderMakeDTOMqttDTO = new MqttDTO<>();
        orderMakeDTOMqttDTO.setCmd(MqttConstants.SYNC_PLAN);
        orderMakeDTOMqttDTO.setPayload(replenishTabList);

        log.info("orderMakeDTOMqttDTO消息:{}", JSONUtil.toJsonStr(orderMakeDTOMqttDTO));

        /**
         * 主题是设备id
         */
        mqttGateway.sendToMqtt(machineId, JSONUtil.toJsonStr(orderMakeDTOMqttDTO));
    }
}
